package com.gitee.l0km.aocache.example.ltw.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import com.gitee.l0km.aocache.config.CacheConfigSupplier;

import static com.gitee.l0km.aocache.MemberCache.INSTANCE;

/**
 * 
 * 方法缓存切面定义<br>
 * @author guyadong
 *
 */
@Aspect
public class AocacheLtwAspect {

	/**
	 * 第三方库切面定义
	 * @param joinPoint
	 * @return
	 * @throws Throwable
	 */
	@Around("rangeGuava() || rangeDateSupport() || rangeCaseSupport() || rangeTypeNameUtils()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		return INSTANCE.around(joinPoint,CacheConfigSupplier.DEFAULT_SUPPLIER);
    }
	
	@Around("aoCacheable() && range()")
    public Object around0(ProceedingJoinPoint joinPoint) throws Throwable {
		return INSTANCE.around(joinPoint);
    }
	@Around("testUserCtor() || genericsCtor()")
	public Object aroundCtor(ProceedingJoinPoint joinPoint) throws Throwable {
		return INSTANCE.around(joinPoint);
	}

    /**
     * 定义切入点为有{@link com.gitee.l0km.aocache.annotations.AoCacheable}注解的所有函数
     */
    @Pointcut("@annotation(com.gitee.l0km.aocache.annotations.AoCacheable)")
    public void aoCacheable() {
    }
    /**
     * 定义切入点为com.gitee.l0km.aocache.example.ltw包下任意类的任意方法执行
     */
    @Pointcut("execution(* com.gitee.l0km.aocache.example.ltw.*.*(..))")
    public void range() {
    }
    /**
     * 定义切入点为net.gdface.utils.DateSupport类的所有静态方法执行
     */
    @Pointcut("execution(* net.gdface.utils.DateSupport.*(..))")
    public void rangeDateSupport() {
    }
    /**
     * 定义切入点为net.gdface.utils.TypeNameUtils类的所有静态方法执行
     */
    @Pointcut("execution(* net.gdface.utils.TypeNameUtils.*(..))")
    public void rangeTypeNameUtils() {
    }
    /**
     * 定义切入点为net.gdface.utils.CaseSupport类的所有静态方法执行
     */
    @Pointcut("execution(* net.gdface.utils.CaseSupport.*(..))")
    public void rangeCaseSupport() {
    }
    /**
     * 定义切入点为com.google.common.primitives.Primitives类下的所有静态方法执行
     */
    @Pointcut("execution(* com.google.common.primitives.*.*(..))")
    public void rangeGuava() {
    }
    /**
     * 定义切入点为 {@link com.gitee.l0km.aocache.example.ltw.AocacheLtwAnnotTest.TestUser}构造方法执行(private除外)<br>
     * aspectJ不能拦截私有构造方法<br>
     * 参见 <a ref="https://stackoverflow.com/questions/63187952/aspectj-intercept-constructor-when-method-reference-is-used">《AspectJ: intercept constructor when method reference is used》</a>
     */
    @Pointcut("call(com.gitee.l0km.aocache.example.ltw.AocacheLtwAnnotTest.TestUser.new(..))")
    public void testUserCtor() {
    }
    /**
     * 定义切入点为 net.gdface.reflection.generics 包下所有类的构造方法
     */
    @Pointcut("call(net.gdface.reflection.generics.*.new(..))")
    public void genericsCtor() {
    }
    public static AocacheLtwAspect aspectOf() {
    	return new AocacheLtwAspect();
    }
}
